# -*- coding:utf-8 -*- #
from probe.core.cmdthread import CmdThread
from probe.logger.logger import getlogger
from probe.conf import configure
from threading import RLock


class ThreadManager(object):
    """create def"""
    def __init__(self):
        #self.threads = {}
        self.using_queue = {}
        self.recycle_queue = {}
        #self.lock = RLock()

    def create_thread(self):
        thread = None
        #self.lock.acquire()
        try:
            for k in self.using_queue.keys():
                if not self.using_queue[k].is_alive():
                    self.recycle_queue[k] = self.using_queue.pop(k)
            k, thread = self.recycle_queue.popitem()
            self.using_queue[id(thread)] = thread
        except KeyError:
            thread  = CmdThread()
            thread.setDaemon(True)
            self.using_queue[id(thread)] = thread
        #self.lock.release()

        for k in self.using_queue.keys():
            if self.using_queue[k].is_terminal:
                self.using_queue.pop(k)

        #terminal_threads = []
        #for tid, t in self.threads.iteritems():
            #if t.is_terminal:
                #terminal_threads.append(tid)
                #continue
            #if not t.is_alive():
                #thread = t
                #break
        #else:
            #thread = CmdThread()
            #thread.setDaemon(True)
            #self.threads[id(thread)] = thread

        #map(lambda tid: self.threads.pop(tid), terminal_threads)
        return thread

    def thread_num(self):
        return len(self.using_queue) + len(self.recycle_queue)
        #return len(self.threads)

    def alive_num(self):
        return len(self.using_queue)
        #alive_num = 0
        #for tid, t in self.threads.iteritems():
            #if t.is_alive():
                #alive_num = alive_num + 1

        #return alive_num

    def is_alive(self, thread):
        if id(thread) in self.using_queue:
            return True
        return False
        #try:
            #return self.threads.get(id(thread)).is_alive()
        #except KeyError:
            #getlogger(configure.logger_path).waring('not such a key')
            #pass
        #return False

    def recycle_all(self):
        for k in self.using_queue.keys():
            self.recycle(self.using_queue[k])

    def recycle(self, thread):
        #self.lock.acquire()
        try:
            thread.recycle()
            self.recycle_queue[id(thread)] = self.using_queue.pop(id(thread))
        except AttributeError:
            getlogger(configure.logger_path).error('thread %s does not exit' % thread)
            #raise AttributeError('thread %s does not exit' % thread)
        except KeyError:
            getlogger(configure.logger_path).error('thread %s does not exit' % thread)
        except:
            print 'recycle'
            pass
        #self.lock.release()
            #raise KeyError('thread %s does not exit' % thread)

    def terminal_all(self):
        #self.lock.acquire()
        for tid in self.using_queue.keys():
            self.using_queue[tid].terminal()
            self.using_queue.pop(tid)

        for tid in self.recycle_queue.keys():
            self.recycle_queue[tid].terminal()
            self.using_queue.pop(tid)
        #self.lock.release()
